package com.yqg.protection.netty.handler;

import com.yqg.protection.netty.service.KeAn5d6cService;
import com.yqg.protection.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Component
@Slf4j
@ChannelHandler.Sharable
public class KeAn5d6cHandler extends AbstractProtocolHandler implements DynamicProtocolHandler {

    @Autowired
    private KeAn5d6cService keAn5d6cService;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        try {
            if (msg instanceof ByteBuf) {
                ByteBuf buf = (ByteBuf) msg;
                // 将ByteBuf转换为十六进制字符串
                String hexData = ByteBufUtil.hexDump(buf).toUpperCase();
                log.info("收到5d6c原始数据: {}", hexData);

                // 创建ProtocolData对象
                ProtocolData protocolData = new ProtocolData();
                protocolData.setHeader(hexData.substring(0,4));
                protocolData.setRawData(hexData);
                protocolData.setCtx(ctx);
                protocolData.setSaveTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                // 生成并发送响应
                byte[] response = generateResponse(protocolData);
                ctx.writeAndFlush(Unpooled.wrappedBuffer(response));
                log.info("已发送5d6c协议响应");

                // 调用处理逻辑
                handle(protocolData);
            } else {
                log.warn("收到非ByteBuf类型数据: {}", msg.getClass().getName());
                ctx.fireChannelRead(msg);
            }
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    public void handle(ProtocolData data) {
        String raw = data.getRawData();
        String src = raw.substring(8, 38);
        String cmd = raw.substring(38, 40);
        String rawData = raw.substring(40, raw.length() - 6);

        executor.execute(() -> dataSaver.saveDataToFileAsync(raw, data.getSaveTime(), src));
        executor.execute(() -> keAn5d6cService.analyzeTemperData(
                ByteUtil.HexToNum(raw.substring(4, 6)),
                data.getSaveTime(),
                rawData,
                cmd,
                src
        ));

    }

    public byte[] generateResponse(ProtocolData data) {
        String raw = data.getRawData();
        String header = data.getHeader();
        String flow = raw.substring(4, 6);
        String version = raw.substring(6, 8);
        String src = raw.substring(8, 38);
        String end = raw.substring(raw.length() - 4);
        return checksumUserTemper(header, flow, version, src, 0x03, 0x00, end);
    }

    @Override
    public String supportHeader() {
        return "5d6c";
    }

    // checksumUserTemper方法
    private byte[] checksumUserTemper(String header, String flow, String version, String src, int cmd, int messageBody, String end) {
        byte[] checksum = ByteUtil.toBytes(flow + version + src + cmd + messageBody);
        String message = header + flow + version + src + cmd + checksumTemper(checksum, checksum.length) + "7e5a";
        log.info(src + "应答心跳包:" + message);
        return ByteUtil.toBytes(message);
    }

    //温湿度传感器校验
    public static byte checksumTemper(byte[] b, int len){
        int sum = 0;
        for(int i = 0; i < len; i++){
            sum = sum + b[i];
        }
        if(sum > 0xff){ //超过了 255，使用补码（补码 = 原码取反 + 1）
            sum = ~sum;
            sum = sum + 1;
        }
        return (byte) (sum & 0xff);
    }
}
